package com.yzr.common.config;

import com.alibaba.druid.filter.config.ConfigTools;
import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @author yzr
 * @date 2021/04/06 15:46
 * @description 数据库连接配置
 **/
@Slf4j
//@Configuration
public class DruidConf {

    /**
     * datasourceUrl 连接数据库url
     */
    @Value("${spring.datasource.url}")
    private String datasourceUrl;

    /**
     * driverClassName 数据库驱动
     */
    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
    /**
     * datasourceUserName 连接数据库的用户名
     */
    @Value("${spring.datasource.username}")
    private String datasourceUserName;

    /**
     * databasePassword 连接数据库密码
     */
    @Value("${spring.datasource.password}")
    private String databasePassword;

    /**
     * 注入数据库公钥
     */
    @Value("${spring.datasource.public-key}")
    private String datasourcePublicKey;

    /**
     * @return dataSource
     * @description 配置数据库自动创建
     * 如果连接地址没有对应的数据库则创建，前提是有root账号，或者是非root账号具有建库的权限
     */
    @Bean
    public DataSource dataSourceConfig() {
        DruidDataSource dataSource = new DruidDataSource();
        String decrypt = null;
        //druid解密
        try {
            decrypt = ConfigTools.decrypt(datasourcePublicKey, databasePassword);
        } catch (Exception e) {
            log.error("公钥解密异常:{}", e.getMessage());
        }
        dataSource.setUrl(datasourceUrl);
        dataSource.setUsername(datasourceUserName);
        //将解密后的密码添加到datasource源
        dataSource.setPassword(decrypt);
        dataSource.setDriverClassName(driverClassName);
        Connection connection = null;
        PreparedStatement state = null;
        try {
            Class.forName(driverClassName);
            // 截取数据库问问好前的连接参数
            String sqlUrl = datasourceUrl.substring(0, datasourceUrl.indexOf("?"));
            // 获取连接数据库的url
            String databasesUrl = sqlUrl.substring(0, sqlUrl.lastIndexOf("/"));
            // 截取数据库名
            String databaseName = sqlUrl.substring(sqlUrl.lastIndexOf("/") + 1);
            // 创建连接
            connection = DriverManager.getConnection(databasesUrl, datasourceUserName, decrypt);
            connection.setAutoCommit(false);
            // 创建传输通道，并设置占位符
            String sql = "create database if not exists ? default character set utf8 COLLATE utf8_general_ci";
            state = connection.prepareStatement(sql);
            // 将数据库名注入到占位符
            state.setString(1, databaseName);
            int execute = state.executeUpdate();
            log.info("sql语句执行状态:{}", execute);
            connection.commit();
        } catch (Throwable e) {
            log.error("数据库连接异常:{}", e.getMessage());
        } finally {
            try {
                if (null != state) {
                    state.close();
                }
                if (null != connection) {
                    connection.close();
                }
            } catch (SQLException throwable) {
                log.error("sql语句异常:{}", throwable.getMessage());
            }
        }
        return dataSource;
    }
}
